/**
 * Copyright 2014  XCL-Charts
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @Project XCL-Charts
 * @Description Android图表基类库
 * @author XiongChuanLiang<br></br>(xcl_168@aliyun.com)
 * @license http://www.apache.org/licenses/  Apache v2 License
 * @version 1.0
 */
package com.gitee.wsl.common.chart.listener.touch

import android.view.MotionEvent
import android.view.View
import com.gitee.wsl.common.draw.gesture.ChartTouch
import com.gitee.wsl.common.chart.sample.XChart
import kotlin.math.abs
import kotlin.math.sqrt

/**
 * @ClassName ChartTouch
 * @Description  上下左右移动图表绘图区及通过两指放大缩小整个图表
 * @author XiongChuanLiang<br></br>(xcl_168@aliyun.com)
 */
class ChartTouchImp(var view: View,
                    var chart: XChart,
                    /**
                  * 用于限定可平移的范围(大于0),默认为1
                  */
                 var panRatio: Float = 1f
) : ChartTouch {

    //单点移动前的坐标位置
    private var oldX = 0.0f
    private var oldY = 0.0f

    //scale
    private var oldDist = 1.0f
    private var newDist = 0.0f
    private var halfDist = 0.0f
    private var scaleRate = 0.0f

    //pan
    private var action = 0
    private var newX = 0.0f
    private var newY = 0.0f


    override fun handleTouch(event: MotionEvent): Boolean {
        when (event.pointerCount) {
            1 -> handleTouch_PanMode(event)
            2 -> handleTouch_Scale(event)
            else -> {}
        }
        return true
    }

    private fun handleTouch_Scale(event: MotionEvent) {
        if (!chart.isZoomEnabled) return
        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> scaleRate = 1.0f
            MotionEvent.ACTION_UP -> {}
            MotionEvent.ACTION_POINTER_UP -> {}
            MotionEvent.ACTION_POINTER_DOWN ->                //两点按下时的距离  
                oldDist = spacing(event)

            MotionEvent.ACTION_MOVE -> {
                newDist = spacing(event)
                if (newDist.compareTo(10.0f) == 1) {
                    halfDist = newDist / 2
                    if (oldDist.compareTo(0.0f) == 0) return
                    scaleRate = newDist / oldDist
                    /**
                     * 目前是采用焦点在哪就以哪范围为中心放大缩小.
                     */
                   /* chart.setScale(
                        scaleRate, scaleRate,
                        event.x - halfDist, event.y - halfDist
                    )*/
                   view.invalidate(
                        chart.left.toInt(),
                        chart.top.toInt(),
                        chart.right.toInt(),
                        chart.bottom.toInt()
                    )
                }
            }

            else -> {}
        }
    }

    private fun handleTouch_PanMode(event: MotionEvent) {
        if(!chart.isScrollEnabled) return
        action = event.action
        if (action == MotionEvent.ACTION_MOVE) {
            if (oldX > 0 && oldY > 0) {
                newX = event.getX(0)
                newY = event.getY(0)
                if (abs(newX - oldX).compareTo(FIXED_RANGE) == 1
                    || abs(newY - oldY).compareTo(FIXED_RANGE) == 1
                ) {
                    setLocation(oldX, oldY, newX, newY)
                    oldX = newX
                    oldY = newY
                }
            }
        } else if (action == MotionEvent.ACTION_DOWN) {
            //在第一个点被按下时触发
            oldX = event.getX(0)
            oldY = event.getY(0)
        } else if (action == MotionEvent.ACTION_POINTER_DOWN) {
            //当屏幕上已经有一个点被按住，此时再按下其他点时触发。		    			    	
        } else if (action == MotionEvent.ACTION_UP //当屏幕上唯一的点被放开时触发
            || action == MotionEvent.ACTION_POINTER_UP
        ) {
            oldX = 0.0f
            oldY = 0.0f
            if (action == MotionEvent.ACTION_POINTER_UP) {
                //当屏幕上有多个点被按住，松开其中一个点时触发（即非最后一个点被放开时）。
                oldX = -1f
                oldY = -1f
            }
        }
    }


    //用来设置图表的位置   	
    private fun setLocation(
        oldX: Float, oldY: Float,
        newX: Float, newY: Float
    ) {
        var xx = 0.0f
        var yy = 0.0f
        val txy = chart.translateXY ?: return
        xx = txy[0]
        yy = txy[1]

        //if(newX < oldX || newY < oldY)	 //加上这个，向右下移时会有没反应
        //{
        xx = txy[0] + newX - oldX
        yy = txy[1] + newY - oldY
        // }


        //不让其滑动出可显示范围
        if (chart.isScrollEnabled) {
            var xr = 1f
            var yr = 1f
            if (panRatio.compareTo(0f) > 0) {
                xr = chart.plotViewport.width / panRatio
                yr = chart.height / panRatio
            }
            if (abs(xx).compareTo(xr) == 1) //
            {
                return
            }
            if (abs(yy).compareTo(yr) == 1) //mChart.getHeight()/2)
            {
                return
            }
        }
       /* chart.setTranslateXY(xx, yy)
        view.invalidate(
            chart.left.toInt(),
            chart.top.toInt(),
            chart.right.toInt(),
            chart.bottom.toInt()
        )*/
    }

    private fun spacing(event: MotionEvent): Float {
        val x = event.getX(0) - event.getX(1)
        val y = event.getY(0) - event.getY(1)
        return sqrt(x * x + y * y)
    }

    companion object{
         const val FIXED_RANGE = 8.0f
    }
}